#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <ctype.h>
#include <dirent.h>

#include "temp.h"
#include "func.h"
#include "private_common.h"


#define HWMON_PATH "/sys/class/hwmon/"

struct hwmondata
{
	int32_t value;
	char name[32];
};
static struct hwmondata temps[250] = {0};
static int temps_num = 0;

static void parse_param(void* ud, void *up, char* st)
{
	struct hwmondata *hd = (struct hwmondata *)ud;
	if(!hd) return;
	char* p = st;
	hd->value = strtod(p, &p)/1000;
}

static int  temp_init(p_monitor_node *ml, const char* ignore)
{
	int k;
	DIR *dir1, *dir2;
	temps_num = 0;
	struct dirent *entry1, *entry2;
	dir1 = opendir(HWMON_PATH);
	if (!dir1) {
		perror("Failed to open thermal directory");
		return 0;
	}
	char tmp[250][MAX_LEN_NAME];
	char name[250][32];
	char hwmon_dir[MAX_LEN_NAME];
	k = 0;
	while ((entry1 = readdir(dir1)) != NULL) {
		if (!strstr(entry1->d_name, "hwmon")) {
			continue;
		}
		sprintf(hwmon_dir, "%s/%s/", HWMON_PATH, entry1->d_name);
		dir2 = opendir(hwmon_dir);
		if (!dir2) {
			perror("Failed to open thermal directory2");
			continue;
		}
		while ((entry2 = readdir(dir2)) != NULL) {
			if (strstr(entry2->d_name, "temp") && strstr(entry2->d_name, "input")) {
				snprintf(tmp[k], MAX_LEN_NAME-1, "%s/%s/%s", HWMON_PATH, entry1->d_name, entry2->d_name);
				snprintf(name[k], 31, "%s/%s", entry1->d_name, entry2->d_name);
				if (exist_file(tmp[k]) == 0) {
					k++;
				}
			}
		}
		closedir(dir2);
	}
	closedir(dir1);
	*ml  = (p_monitor_node)malloc(sizeof(monitor_node)*k);
	for (int i = 0;i < k; i++) {
		snprintf(temps[i].name, 31, "%s", name[i]);
	        init_monitor_info_interface(&((*ml+i)->oper), parse_param, (void*)(&(temps[i])), NULL);
		init_monitor_node(*ml+i, tmp[i], 5, 0);
	}
	temps_num = k;
	return k;
}

static void temp_update(p_monitor_node *ml)
{
	for (int i = 0;i < temps_num;i++) {
		update_monitor_node(*ml+i);
	}
}

static void temp_clean() 
{
	temps_num = 0;
}

static void temp_to_json(cJSON* json) 
{
	cJSON *item;
	for (int i = 0;i < temps_num; i++) {
		item = cJSON_GetObjectItemCaseSensitive(json, temps[i].name);
		if (item) {
			cJSON_SetNumberValue(cJSON_GetObjectItem(json, temps[i].name), temps[i].value);
		} else {
			cJSON_AddNumberToObject(json, temps[i].name, temps[i].value);
		}
	}

}

static uint32_t temp_to_text(char* buffer, uint32_t size)
{
        char line[5][64];
        uint32_t k1 = 0, k2 = size;
        int r;
	for (int i = 0;i < temps_num; i++) {
		r = snprintf(buffer+k1, k2, "temp,%s,%d\n", temps[i].name, temps[i].value);
                if (r <= 0) return k1;
                k1 += r;
                if (k1 >= size) break;
                k2 -= r;
        }

        return k1;
}

void temp_task_init(ptask t, char* _ignore, uint16_t _uf)
{
        t->init    = temp_init;
        t->update  = temp_update;
        t->to_json = temp_to_json;
        t->clean   = temp_clean;
        t->json    = NULL;
        t->ignore  = _ignore;
        t->uf      = _uf;
        t->cu      = 0;
	t->to_text = temp_to_text;
}


